/*
 * Matthew Cramer, Jesse Martinez, Marc Mendoza 
 * CSE 325 Lab 3
 * File: TestingInterface.c
 * Description: Manager that handles calls to the Queue.  This is called from
 *              the Process manager to perform the functions to the stack.
 *
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../QueueManager/QueueManager.h"
#include "../ProcessManager/ProcessManager.h"
#include "../Scheduler/Scheduler.h"

void list(int);

int main(int argc, char *argv[])
{
	char command[80], argument[6][10];
	char *temp;
	int exit = 1, check, manualInput = 1, sched=5;
	//sched == 1 Fair Share
	//shed == 2 Priority 
	FILE *file;
	
	if(argc == 2)
	{
		file = fopen ( argv[1], "r" );
		manualInput = 0;
	}
	
	
	
	while(exit != 0)
	{
		printf("\nScheduler: \n");
		printf("1) Init_Sched [ general_purpose | interactive]\n");
		printf("2) Create_Proc [psw & page-table & reg0 & reg1 & reg2]\n"); 
		printf("3) list [queue_name | all | SCHED]\n");
		printf("4) unwait [pid]\n");
		printf("5) eoquantum\n");
		printf("6) eolife\n");
		printf("7) wait\n");
		printf("8) go\n");
		printf("9) resetQueues\n");
		printf("10) exit\n");
        printf("\n ");
		
		//waits for user to input commands
		if(manualInput == 1)
		{
			scanf("%[^\n]", command);
			getchar();
		}
        
		//pulls in commands from a file
		else if(manualInput == 0)
		{
			if(fgets(command, sizeof command, file) != NULL)
			{
			printf("%s\n", command);
			}
		}
		
		//uses a string tokenizer to split files based on whitespace
		temp = strtok(command, " ");
		strcpy(command, temp);
        
		//new process is create by calling toNew and will receive -1 or -8 if there is an error
		if(strcmp(command, "Init_Sched") == 0)
		{
			int j = 0;
			temp = strtok(NULL, " ");
			if(temp != NULL)
			{
				strcpy(command, temp);
				if(strcmp(command, "general_purpose")==0)
				{
					printf("You have chosen the general purpose scheduler\n");
					sched =1;
				}
				else if(strcmp(command, "interactive") ==0)
				{
					printf("you have chosen the interactive scheduler\n");
					sched =2;
				}
				else
				{
				printf("Not the correct input for the Scheduler try again\n");
				}
				clearQueues();
			}
			else
			{
					printf("ERROR: Not the correct amount of arguements");
			}
		}
		
		else if((strcmp(command, "Create_Proc") == 0) && (sched == 1 || sched ==2) )
		{
			int i = 0;
			temp = strtok(NULL, " ");
            
			//the [pid | psw |[age-table |reg0 |reg 1 | reg2] is extracted from input
			while(temp != NULL)
			{
                
				strcpy(argument[i], temp);
				temp = strtok(NULL, " ");
				i++;
			}
            if(i == 5 || i == 6)
            {
				if(sched == 1)
				{
					check = createProcess(atoi(argument[0]), atoi(argument[1]), atoi(argument[2]), atoi(argument[3]),
                                  atoi(argument[4]), atoi(argument[5]));
				}
                else if( i == 5)
                {
                    check = newProcess(atoi(argument[0]), atoi(argument[1]), atoi(argument[2]), atoi(argument[3]),
                                  atoi(argument[4]), atoi(argument[5]));
                }
                else
                {
                    check = newProcess(atoi(argument[0]), atoi(argument[1]), atoi(argument[2]), atoi(argument[3]),
                                  atoi(argument[4]), atoi(argument[5]));
                }
				if(check == -8 || check == -1)
					printf("ERROR: Max number of processes running\n");
				else if(check > 0)
					printf("Process created with PID %d\n", check); 
            }
            else
            {
                printf("ERROR: Not the correct amount of arguements");
            }
			
		}
        
		//based on which queue is to be listed, list() is called with number
		//corresponding to queue
		else if((strcmp(command, "list") == 0) && (sched == 1 || sched ==2))
		{
			temp = strtok(NULL, " "); //get attribute of list
			if(temp != NULL)
			{
				if(strcmp(temp, "ready") == 0)
					list(2);
				else if(strcmp(temp, "running") == 0)
					list(3);
				else if(strcmp(temp, "wait") == 0)
					list(4);
				else if(strcmp(temp, "terminate") == 0)
					list(5);
				else if(strcmp(temp, "SCHED") == 0)
				{
					int headSched = getHead(2);
					process_control_block *tempQueue1 = getQueue(2);
					if(headSched != -1)
					{
						if(sched == 1)
						{
						printf("Next Scheduled Process:\n");
						printf("PID: %d\nPSD: %d\nPage Table: %d\nReg1: %d\nReg2: %d\nReg3: %d\nGroup: %d\n",
							tempQueue1[headSched].pid,
							tempQueue1[headSched].psw,
							tempQueue1[headSched].pageTable,
							tempQueue1[headSched].regs[0],
							tempQueue1[headSched].regs[1],
							tempQueue1[headSched].regs[2],
							tempQueue1[headSched].group);
						}
						else if(sched == 2)
						{
							int temp = findHighPriority();
							printf("Next Scheduled Process:\n");
							printf("PID: %d\nPSD: %d\nPage Table: %d\nReg1: %d\nReg2: %d\nReg3: %d\nPriority: %d\n",
								tempQueue1[temp].pid,
								tempQueue1[temp].psw,
								tempQueue1[temp].pageTable,
								tempQueue1[temp].regs[0],
								tempQueue1[temp].regs[1],
								tempQueue1[temp].regs[2],
								tempQueue1[temp].priority);
						}	
					}
					else
					{
						printf("No Process Scheduled Next\n");
					}
		
				}
				else if((strcmp(temp, "all") == 0)&& (sched == 1 || sched ==2))
				{
					int i = 0;
					for(i=2; i < 6; i++) 
					{
						list(i);
						printf("\n");
					}
				}
			}
			else
			{
				printf("ERROR: Not the correct amount of arguements");
			}
		}
        
		//unwaiting a process has the possibility of two errors:
		//-process not found
		//-process unable to moved into ready
		else if((strcmp(command, "unwait") == 0)&& (sched == 1 || sched ==2))
		{
			temp = strtok(NULL, " ");
			if(temp != NULL)
			{
				check = Scheduler(sched, 1, (atoi(temp)));
				if(check == -2)
					printf("ERROR: Process not found\n");
				else if(check == -3)
					printf("ERROR: Process could not be moved from the Waiting to Ready queue\n");
				else
					printf("Process %d was moved to the Ready queue successfully\n",check);
			}
			else
			{
				printf("ERROR: Not the correct amount of arguements");
			}
		}
        
		//process is moved from running to ready
		else if((strcmp(command, "eoquantum") == 0)&& (sched == 1 || sched ==2))
		{
			check = Scheduler(sched, 2, 0);
			
			if(check == -4)
				printf("ERROR: Process could not be moved from the Running to Ready queue\n");
			else
				printf("Process %d was successfully moved to Ready queue\n",check);
		}
        
		//process is terminated
		else if((strcmp(command, "eolife") == 0)&& (sched == 1 || sched ==2))
		{
			check = Scheduler(sched, 3, 0);
			
			if(check == -5)
				printf("ERROR: Process could not be terminated\n");
			else
				printf("Process %d was terminated successfully\n", check);
		}
		
		//process is moved from running to waiting
		else if((strcmp(command, "wait") == 0)&& (sched == 1 || sched ==2))
		{
			check = Scheduler(sched, 4, 0);
			
			if(check == -6)
				printf("ERROR: Process could not be placed into waiting\n");
			else
				printf("Process %d was placed into wait queue successfully\n",check);
		}
        
		else if((strcmp(command, "go") == 0)&& (sched == 1 || sched ==2)) //1 for processManagerFunction
		{
			check = Scheduler(sched, 0, 0);
			if(check == -7 || check == -12)
				printf("ERROR: There are no processes ready to be run\n");
			else if(check == -11)
                printf("Process still in running Queue\n",check);
            else
				printf("go was succcessful! Process %d is being run\n",check);
		}
		
		else if((strcmp(command, "resetQueues") == 0)&& (sched == 1 || sched ==2)) //1 for processManagerFunction
		{
			clearQueues();
			printf("Queues were reset\n");
		}
		
		else if(strcmp(command, "exit") == 0)
		{
			exit = 0;
		}
        else if(sched != 1 && sched !=2)
        {
            printf("Error: Select Scheduler\n");
        }
        else
        {
            printf("Input not recognized\n");
        }
	}
    
	return 0;
}

//prints list based on which number is passed
void list(int whichQueue)
{
	int head = getHead(whichQueue), tail = getTail(whichQueue);
	process_control_block *tempQueue = getQueue(whichQueue);
	int size = getSizeOfQueue(whichQueue);
    
	if(whichQueue == 2)
		printf("Ready Queue:\n");
	else if(whichQueue == 3)
		printf("Running Queue:\n");	
	else if(whichQueue == 4)
		printf("Wait Queue:\n");
	else if(whichQueue == 5)
		printf("Terminate Queue:\n");
	
    
	if(size==0)
		printf("Empty\n");
	//iterates through queue
	else
	{
		int temp[20];
		
		int var = 0;
        int j=0;
		int k=0;
		int e, i = head;
		int smallest;
		for(e=0; e<size; e++)
		{
			temp[e] = tempQueue[i].pid;
			i = tempQueue[i].nextIndex;
            printf("%d\n",temp[e]);
		}

        //Print out PIDs in numerical order
		while(j<size)
		{
			smallest = temp[j];
            
			while(k<size)
			{
				if(smallest > temp[k])
				{
					smallest = temp[k];
					var = k;
				}
				k++;
			}
			temp[var] = temp[j];
            temp[j] = smallest;
		    printf("Process ID: %d\n", temp[j]);
			j++;    
            k=j;
            var=j;
		}
	}
}
